package ch08 {
	/**
	 * 三角和 3D(绘制圆柱)
	 * @author jianping.shenjp
	 */
	import __AS3__.vec.Vector;
	import flash.display.Bitmap;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.display.TriangleCulling;
	import flash.events.Event;

	[SWF(backgroundColor=0xffffff)]
	public class ImageTube extends Sprite {
		[Embed(source="../../assets/image.jpg")]
		private var ImageClass:Class;
		private var vertices:Vector.<Number> = new Vector.<Number>();
		private var indices:Vector.<int> = new Vector.<int>();
		private var uvtData:Vector.<Number> = new Vector.<Number>();
		private var bitmap:Bitmap;
		private var sprite:Sprite;
		private var res:Number = 60; //分别率,决定三角的尺寸
		private var cols:int = 20; //行数
		private var rows:int = 6; //列数
		private var centerZ:int = 200;
		private var focalLength:Number = 250;
		private var radius:Number = 200; //圆柱半径

		public function ImageTube(){
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			sprite = new Sprite();
			sprite.x = 400;
			sprite.y = 400;
			addChild(sprite);
			bitmap = new ImageClass() as Bitmap;
			makeTriangles();
			draw();
		}

		private function draw():void {
			sprite.graphics.clear();
			sprite.graphics.beginBitmapFill(bitmap.bitmapData);
			/**
			 * 背面剔除:
			 * positive 剔除只绘制逆时针的三角，
			 * negative 剔除只绘制顺时针的。
			 * 如果设置剔除为 none，就都绘制。
			 */
			var g:Graphics = sprite.graphics;
			g.drawTriangles(vertices, indices, uvtData, TriangleCulling.NEGATIVE);
			g.endFill();
			g.lineStyle(0, 0, .5);
			g.drawTriangles(vertices, indices, uvtData, TriangleCulling.NEGATIVE);
			g.endFill();
		}

		private function makeTriangles():void {
			for (var i:int = 0; i < rows; i++){
				for (var j:int = 0; j < cols; j++){
					var angle:Number = Math.PI * 2 / (cols - 1) * j;
					var xpos:Number = Math.cos(angle) * radius;
					var ypos:Number = (i - rows / 2) * res;
					var zpos:Number = Math.sin(angle) * radius;
					var scale:Number = focalLength / (focalLength + zpos + centerZ);
					vertices.push(xpos * scale, ypos * scale);
					/**
					 * uvt 中的 t
					   突然想起一个东西：t，它特别用在3D 绘制时修正位图的缩放。在前一个例子中，我们计算缩
					   放是基于每个点的z 坐标，然后使用这个缩放值调整映射于屏幕上的x,y 坐标，最后以此创建用于
					   绘制三角形的顶点。这个缩放值同样要作为每个顶点所对应的t。这时，它表示任意两点间像素的
					   缩放间隔。打开你的想象空间，设想一道篱笆，其栅栏间距相等，那么距离越远的栅栏凑的越近，
					   越靠前的栅栏分得越开。t 的意义就在于此，只不过对应的东西是像素而不是栅栏。没有 t，点与
					   点之间是相等的，结果就会是图像看似被扭曲了。
					   t 作为是u,v 后的一个值加入uvtData 中，好像这样：
					   var scale:Number = focalLength / (focalLength + zpos + centerZ);
					   vertices.push(xpos * scale, ypos * scale);
					   uvtData.push(j / (cos - 1), i / (rows - 1));
					   uvtData.push(scale);
					   你可能正在想，这样不是搞乱了uvtData 嘛，之前是两个值为一组，现在是三个值为一组。好
					   在，drawTriangles 能聪明的分辨出来。如果 uvtData 和vertices 长度一样，就认为只含有u,v，
					   如果uvtData 的长度是vertices 长度的1.5 倍，就认为是含有t 的。
					 */
					uvtData.push(j / (cols - 1), i / (rows - 1));
					uvtData.push(scale);
					if (i < rows - 1 && j < cols - 1){
						indices.push(i * cols + j, i * cols + j + 1, (i + 1) * cols + j);
						indices.push(i * cols + j + 1, (i + 1) * cols + j + 1, (i + 1) * cols + j);
					}
				}
			}
		}
	}
}